home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Libraries
/
File class library
/
sources
/
CIsleFile.c
< prev
next >
Wrap
Text File
|
1992-10-08
|
8KB
|
328 lines
/*
CIsleFile.c
Superclass: CFile
CFile plus directory manipulation.
October 8, 1992 isl
*/
#include <CIsleFile.h>
extern OSType gSignature; // Owner stamp
/*=====================*/
/*===---------------===*/
void CIsleFile::IIsleFile(void)
Begin
IFile();
fSuper= False; // We will assume the worse
if (gSystem.hasGestalt)
{
long response; // The response from the Gestalt enquiry
if (Gestalt(gestaltFindFolderAttr, &response) == noErr)
if ((response & (1 << gestaltFindFolderPresent)))
fSuper= True; // We may rely on System 7 Finder goodies
}
End
/*===---------------===*/
void CIsleFile::CreateNew(OSType creator, OSType type)
Begin
if (ExistsOnDisk())
MoveToTrash(); // Get rid of this copy
FailOSErr( HCreate(volNum, dirID, name, creator, type) );
End
/*===---------------===*/
void CIsleFile::ResolveFileAlias(void)
Begin
FSSpec fileSpec;
Boolean isFolder;
Boolean wasAliased;
if (!gSystem.hasAliasMgr) return;
CopyPString(name, fileSpec.name);
fileSpec.parID= dirID;
fileSpec.vRefNum= volNum;
FailOSErr( ResolveAliasFile(&fileSpec, True, &isFolder, &wasAliased) );
if (wasAliased) // Copy back specification
{
CopyPString( fileSpec.name, name);
dirID= fileSpec.parID;
volNum= fileSpec.vRefNum;
}
End
/*===---------------===*/
void CIsleFile::GetPath(Str255 path, Str255 delimiter)
Begin
path[0]= 0; // Initialize the path
CollectPath(path, delimiter, (FSSpec*)Null);
End
/*===---------------===*/
void CIsleFile::CollectPath(Str255 path, Str255 delimiter, FSSpec* leafSpec)
Begin
FSSpec fileSpec; // The file/folder specification
long directory; // The target's directory
OSErr error; // Possible error condition
Str255 leafName= "\p"; // The name of a leaf in the directory tree
if (!leafSpec)
{
GetFSSpec(&fileSpec); // Specifications of the actual file
CollectPath(path, delimiter, &fileSpec);
}
else
{
if (leafSpec->parID == fsRtParID)
{
return; // We are the root -- the end of recursion
}
else
{ // We have a parent directory
directory= leafSpec->parID;
error= MakeFSSpec(volNum, directory, leafName, kDirectory, &fileSpec);
// I should really be checking for errors,
// but the only possible error is file not found
// and it is not bloody likely
CollectPath(path, delimiter, &fileSpec);
ConcatPStrings(fileSpec.name, delimiter);
}
}
ConcatPStrings(path, fileSpec.name);
End
/*===---------------===*/
Boolean CIsleFile::IsStationery(void)
Begin
Boolean fStationery= False; // Assume not
if (fSuper)
{ // We are using System 7 or later
FInfo fileInfo; // Information about our file
GetMacFileInfo(&fileInfo);
if (fileInfo.fdFlags & kStationery)
fStationery= True;
}
return fStationery;
End
/*===---------------===*/
void CIsleFile::GetMacCatInfo(CInfoPBPtr specs)
Begin
specs->dirInfo.ioCompletion= Null;
specs->dirInfo.ioNamePtr= name;
specs->dirInfo.ioVRefNum= volNum;
specs->dirInfo.ioFDirIndex= kDefault;
specs->dirInfo.ioDrDirID= dirID;
FailOSErr( PBGetCatInfo(specs, False) );
End
/*===---------------===*/
void CIsleFile::SetMacCatInfo(CInfoPBPtr specs)
Begin
specs->dirInfo.ioCompletion= Null;
specs->dirInfo.ioNamePtr= name;
specs->dirInfo.ioVRefNum= volNum;
specs->dirInfo.ioFDirIndex= kDefault;
specs->dirInfo.ioDrDirID= dirID;
FailOSErr( PBSetCatInfo(specs, False) );
End
/*===---------------===*/
void CIsleFile::SetMacFileInfo(FInfo* fileInfo)
Begin
FailOSErr( HSetFInfo(volNum, dirID, name, fileInfo) );
End
/*===---------------===*/
Boolean CIsleFile::GoodType(OSType fileType)
Begin
FInfo fileInfo;
GetMacFileInfo(&fileInfo);
return (fileType == fileInfo.fdType);
End
/*===---------------===*/
void CIsleFile::MakeStationery(Boolean fStationery)
Begin
if (fSuper)
{ // We are using System 7 or later
FInfo fileInfo; // Information about our file
GetMacFileInfo(&fileInfo);
// Toggle the stationery flag to ON
if (fStationery)
fileInfo.fdFlags|= kStationery;
else
fileInfo.fdFlags&= (~kStationery);
SetMacFileInfo(&fileInfo);
}
End
/*===---------------===*/
void CIsleFile::FindCreatorType(short vRefNum, long directory, OSType creator, OSType type, Boolean inside)
Begin
CInfoPBRec specs; // Specifics of the file or folder
OSErr error; // A possible error condition
register short index; // Entry index
specs.hFileInfo.ioCompletion= Null;
specs.hFileInfo.ioNamePtr= name;
specs.hFileInfo.ioVRefNum= vRefNum;
for(index= 1; !fGood; index++)
{
specs.hFileInfo.ioDirID= directory;
specs.hFileInfo.ioFDirIndex= index;
error= PBGetCatInfo(&specs, False);
if (error)
return; // No more entries!
if ((specs.hFileInfo.ioFlFndrInfo.fdType == type
&& specs.hFileInfo.ioFlFndrInfo.fdCreator == creator))
{
volNum= vRefNum; // Set volume number
dirID= directory; // Set the directory
// The name is set for us!
fGood= True; // Found what we were looking for.
return;
}
if (inside && (specs.hFileInfo.ioFlAttrib & kDirTest))
FindCreatorType(vRefNum, specs.dirInfo.ioDrDirID, creator, type, True);
}
End
/*===---------------===*/
OSErr CIsleFile::MakeFSSpec(short vRefNum, long directory, StringPtr leafName, short index, FSSpec* fileSpec)
Begin
OSErr error; // A possible error condition
if (fSuper)
{ // We can use System 7 calls!
error= FSMakeFSSpec(vRefNum, directory, leafName, fileSpec);
}
else
{ // Bleagh, System 6
CInfoPBRec specs; // Current leaf specifications
specs.dirInfo.ioCompletion= Null;
specs.dirInfo.ioNamePtr= leafName;
specs.dirInfo.ioVRefNum= vRefNum;
specs.dirInfo.ioFDirIndex= index;
specs.dirInfo.ioDrDirID= directory;
if (error= PBGetCatInfo(&specs, False) )
ErrorAlert(error, 0); // Display a generic error alert
else
{
fileSpec->vRefNum= vRefNum; // The volume reference number
fileSpec->parID= specs.dirInfo.ioDrParID; // Current leaf's parent directory
CopyPString(specs.dirInfo.ioNamePtr, fileSpec->name); // Current leaf's name (file or folder)
error= noErr;
}
}
return error;
End
/*===---------------===*/
void CIsleFile::MoveToTrash(void)
Begin
if (fSuper)
{ // Relocate into the Trash
short trashVolume; // Volume containing our Trash folder (should be same)
long trashDirID; // ID of the local Trash directory
FSSpec trashSpec; // Specifications of the trash file
FSSpec goodSpec; // Specifications of the good file
FInfo fileInfo; // File information record
FailOSErr( FindFolder(volNum, kTrashFolderType, kDontCreateFolder, &trashVolume, &trashDirID) );
GetFSSpec(&goodSpec); // Specifications of the current file (to be removed)
GetMacFileInfo (&fileInfo);
SpecifyHFS(name, trashVolume, trashDirID);
CreateUniqueNew(fileInfo.fdCreator, fileInfo.fdType);
GetFSSpec(&trashSpec); // Create the impostor in ther Trash Folder
FailOSErr( FSpExchangeFiles (&trashSpec, &goodSpec) );
SpecifyFSSpec(&goodSpec); // We are working with the original again
}
ThrowOut(); // Simply delete the file
End
/*===---------------===*/
void CIsleFile::CreateUniqueNew(OSType creator, OSType type)
Begin
OSErr error; // Possible error condition
Str63 bogusName; // We need to create a new name to avoid a conflict
char* lastLetter; // The last letter in the name
char unique; // A character that will make the name unique
unique= '0';
if (*name < 63)
(*name)++; // We will add a character
lastLetter= (char*)(name + *name);
do // We need to rename it
{
*lastLetter= unique++; // Insert the unique character and increment it in case we will need it
if ((unique > 'Z') && ExistsOnDisk())
{
ThrowOut(); // This has gone far enough. Just delete the sucker!
break;
}
}
while (ExistsOnDisk());
CreateNew(creator, type);
End
/*===---------------===*/
/*=====================*/